﻿using GEPL.ViewModels;
using System;
using System.Runtime.Serialization;
using Gdi = System.Drawing;

namespace GEPL.Projects
{
    /// <summary>
    /// Represents a turtle graphics project
    /// </summary>
    [Serializable]
    public class TurtleProject : Project
    {
        /// <summary>
        /// The "turtle graphics" output for program
        /// </summary>
        public TurtleOutput Output { get; set; }

        public TurtleProjectSettingsModel TurtleProjectSettings { get; set; }

        /// <summary>
        /// We save the image of the turtle's tracks just
        /// before we draw the turtle icon.  That way, when
        /// the turtle moves, we don't have to worry about erasing
        /// the icon.
        /// </summary>
        public Gdi.Bitmap SavedImage { get; private set; }

        /// <summary>
        /// Creates an instance of class
        /// </summary>
        /// <param name="output">The "turtle graphics" output for program</param>
        public TurtleProject(TurtleOutput output)
        {
            Init(output);
        }

        public TurtleProject(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            TurtleProjectSettings = (TurtleProjectSettingsModel)info.GetValue(nameof(TurtleProjectSettings), typeof(TurtleProjectSettingsModel));
        }

        public void Init(TurtleOutput output)
        {
            Output = output;
            SavedImage = new Gdi.Bitmap(output.Bitmap);
            output.DrawTurtle();
            output.Refresh();

            SetVariables();
        }

        /// <summary>
        /// Sets variables that can be used from Python code
        /// </summary>
        private void SetVariables()
        {
            Scope.SetVariable("Turtle", Output);
        }

        /// <summary>
        /// Overrides standard code execution.
        /// It's necessary so we can print the "turtle" icon
        /// </summary>
        public override void Execute()
        {
            Output.Graphics.DrawImage(SavedImage, 0, 0);

            base.Execute(() =>
            {
                SavedImage.Dispose();
                SavedImage = new Gdi.Bitmap(Output.Bitmap);
                Output.DrawTurtle();
                Output.Refresh();
            });
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);

            info.AddValue(nameof(TurtleProjectSettings), TurtleProjectSettings, typeof(TurtleProjectSettingsModel));
        }
    }
}